package ee122Networking;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.List;

public class RouterSenderThread extends Thread {
	protected DatagramSocket socket;
	protected List<byte[]> internalStorage; 
	protected List<byte[]> priorityStorage = null;
	protected int priorityDestination;
	
	public RouterSenderThread (List<byte[]> internalStorage) {
		this.internalStorage = internalStorage;
		try {
			socket = new DatagramSocket();
		} catch (SocketException e) {
			System.out.println("Socket could not be opened");
			e.printStackTrace();
		}
		System.out.println("Router socket opened. Waiting to send on port " + socket.getLocalPort());
	}
	
	public RouterSenderThread  (List<byte[]> internalStorage, List<byte[]> priorityStorage) {
		this(internalStorage);
		this.priorityStorage = priorityStorage;
	}
	public void run() {
		byte[] outgoingData = null;
		while(true) {
			outgoingData = null;
			if (priorityStorage != null) {
				synchronized(internalStorage) {
					synchronized(priorityStorage) {
						 if (!priorityStorage.isEmpty()) {
							outgoingData = priorityStorage.remove(0);
						 } else {
							 if (!internalStorage.isEmpty()) {
								 outgoingData = internalStorage.remove(0);
							 }
						 }
					}
				}
			} else {
				synchronized(internalStorage) {
					 if (!internalStorage.isEmpty()) {
						 outgoingData = internalStorage.remove(0);
					 }
				}
			}
			if (outgoingData != null) {
				processAndSendData(outgoingData);
			}
		}
	}

	private void processAndSendData(byte[] outgoingData) {
		// get the destination port from the data
		int routerPort = 0;
		byte[] destPortData = new byte[4];
		System.arraycopy(outgoingData, 4, destPortData, 0, 4);
		ByteArrayInputStream bis = new ByteArrayInputStream(destPortData);
		DataInputStream dis = new DataInputStream(bis);
		try {
			routerPort = dis.readInt();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			//create a new packet and send it
			DatagramPacket packet = new DatagramPacket(outgoingData, outgoingData.length, InetAddress.getByName("localhost"), routerPort);
			
			socket.send(packet);
			// then delay a bit until it's time to send a new packet
			long before = System.currentTimeMillis();
			Thread.sleep(10);
			long after = System.currentTimeMillis();
			System.out.println("Slept for " + (after - before) + " ms");
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println(e + "==== cannot send packet");
			System.exit(1);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
